package edu.ncsu.csc;

import java.io.IOException;
import java.util.Random;

import javax.microedition.io.Connector;
import javax.microedition.io.Datagram;

import com.sun.spot.io.j2me.radiogram.RadiogramConnection;
import com.sun.spot.peripheral.ChannelBusyException;
import com.sun.spot.sensorboard.peripheral.LEDColor;
import com.sun.spot.util.Queue;

/**
 * Processes a Queue by removing Datagrams and broadcasting them.
 * 
 * @author David A. Boyuka, II
 */
public class RadioManager extends Thread implements DatagramFactory {
	private Random rand = new Random();
	
	private Queue dgQueue;
	private RadiogramConnection conn;
	
	public RadioManager(Queue dgQueue) throws IOException {
		this.dgQueue = dgQueue;
		
		conn = (RadiogramConnection)Connector.open("radiogram://broadcast:101");
		conn.setMaxBroadcastHops(1);
	}

	public void run() {
		try {
			while (true) {
				Datagram dg = (Datagram)dgQueue.get();
				sendDatagram(dg);

				LEDHelper.setColorAll(LEDColor.GREEN);
				// this flash speed will allow a datarate of 13.15 datagrams/second
				// or about 200 hz assuming 15 samples per datagram
				LEDHelper.flash(10);
			}
		} catch (InterruptedException ie) {
			closeConnection();
			System.out.println("RadioManager thread interrupted, terminating...");
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
	}

	private void closeConnection() {
		try { conn.close(); } catch (IOException ioe) {}
		
	}

	private synchronized void sendDatagram(Datagram dg) throws IOException, InterruptedException {
		// Retry sending until the packet goes through, or there is an unrecoverable error
		while (true) {
			try {
				conn.send(dg);
				return;
			} catch (ChannelBusyException cbe) { // This can happen sometimes, just retry in a bit
				System.out.println("Error sending datagram over radio, retrying in about 50ms: " + cbe);
				Thread.sleep(40 + rand.nextInt(20));
			}
		}
	}
	
	public synchronized Datagram newDatagram() {
		try {
			return conn.newDatagram(conn.getMaximumLength());
		} catch (IOException ioe) {
			return null;
		}
	}
}
